import smtpd, asyncore
from email import Parser
import json, threading  # does this make us 2.6 specific?  if so, boo.
import plex

# Copyright (C) Mark Pesce, begun 12 July 2010

# api-smtp implements a very simple API for Plexus, based on SMTP
# This API talks to the Plex, and will eventually talk to the Sharers.
# A companion API, api-pop3, running POP3, will eventually talk to the Listeners...

class APIServer(smtpd.SMTPServer):

	def process_plexus(self, msg):
		print ('Plexus message received, processing...')
		#for part in msg.walk():
		#	print part
		# Is there an attachment?  
		# If so, this should be an hCard/jCard of some sort
		if msg.is_multipart():
			print ("We have received a multipart message")
		else:
			print ("No attachment, ignoring...")
			return

		# Theoretically we can skip the first payload and process all payloads after that
		# They should, ideally, be hCards or jCards.
		x = msg.get_payload()	# Should return iterator
		count = False
		jCard = {}
		for card in x:
			if count == False:
				count = True
				continue	# Throw first one away
			jCardStr = card.get_payload(decode=True)
			#print("Attachment:\n")
			#print(jCardStr + "\n")
			
			# OK, so is this valid JSON?
			try:
				jCard = json.loads(jCardStr)
				print("Successful conversion to JSON!")

			except ValueError:
				print("Not valid JSON, ignoring...")

			# This is where we will pass it along to the Plex
			plexy = plex.Plexbase()
			plexy.add_from_jcard(jCard)
			print('We seem to have added that card successfully')
			plexy.close()

	#This is the callback from SMTPServer that all SMPTServers
	#must implement to handle messages
	def process_message(self, peer, mailfrom, rcpttos, data):

		#Parse the message into an email.Message instance
		p = Parser.Parser()
		m = p.parsestr(data)
		print "Received Message"
		
		#See if it is a message to Plexus
		if m.has_key('To') and m['To'] == 'plexus@relationalspace.org':
			self.process_plexus(m)
		else :
			# Here is where we'll catch other messages
			# To be shared through Plexus.  But not yet.
			print "Unknown Email message"
			print m

def SMTPthread():
	#This is the 2.2 way of running asynchronous servers
	print ('Starting SMTP server on port 4182...')	
	server = APIServer(("localhost", 4182), (None, 0))
	print('SMTP server started.')
	asyncore.loop(count=0)	

# Basic funtion that all API modules must implement
def APIStart(stuff):
	apithread = threading.Thread(target=SMTPthread)
	apithread.start()

if __name__ == '__main__':
	APIStart("__main__")